package common

import (
	"alertmanagerWebhook/config"
	"alertmanagerWebhook/global"
	"alertmanagerWebhook/utils"
	"encoding/json"
	"fmt"
)

type NotificationService struct {
	transformerFactory *TransformerFactory
}

func NewNotificationService() *NotificationService {
	return &NotificationService{
		transformerFactory: NewTransformerFactory(),
	}
}

func (s *NotificationService) Send(notification config.Notification, platform string) error {
	global.Logger.Infof("开始处理%s平台通知请求", platform)

	if !utils.IsPlatformEnabled(platform) {
		err := fmt.Errorf("%s notifications are disabled", platform)
		global.Logger.Errorf("%s告警通道未启用", platform)
		return err
	}

	// 创建MessageGenerator实例
	msgGenerator, err := NewMessageGenerator()
	if err != nil {
		return fmt.Errorf("创建消息生成器失败: %w", err)
	}
	defer msgGenerator.redisUtil.Close()

	var sendSuccess bool
	switch platform {
	case "wechat":
		global.Logger.Debugf("准备发送%s markdown格式通知", platform)
		if err := s.sendMarkdownNotification(notification, platform); err != nil {
			global.Logger.Errorf("%s通知发送失败: %v", platform, err)
		} else {
			sendSuccess = true
		}
	case "dingding":
		global.Logger.Debugf("准备发送%s dingding格式通知", platform)
		if err := s.sendDingNotification(notification, platform); err != nil {
			global.Logger.Errorf("%s通知发送失败: %v", platform, err)
		} else {
			sendSuccess = true
		}
	case "email":
		global.Logger.Debug("准备发送邮件通知")
		msg, err := s.SendEmailNotification(notification)
		if err != nil {
			global.Logger.Errorf("邮件通知准备失败: %v", err)
		} else if err := s.sendEmailMessage(msg); err != nil {
			global.Logger.Errorf("邮件发送失败: %v", err)
		} else {
			sendSuccess = true
		}
	default:
		err := fmt.Errorf("unsupported platform: %s", platform)
		global.Logger.Errorf("不支持的平台类型: %s", platform)
		return err
	}

	// 只有发送成功且是恢复告警时才删除key
	if sendSuccess && notification.Status == "resolved" {
		for _, alert := range notification.Alerts {
			if err := msgGenerator.ConfirmAlertResolution(alert.Fingerprint); err != nil {
				global.Logger.Errorf("删除告警key失败: %v", err)
			}
		}
	}

	return nil
}

// sendMarkdownNotification 处理markdown格式的通知
func (s *NotificationService) sendMarkdownNotification(notification config.Notification, platform string) error {
	global.Logger.Debugf("创建%s markdown转换器", platform)
	transformer, err := s.transformerFactory.CreateTransformer("markdown")
	if err != nil {
		global.Logger.Errorf("创建markdown转换器失败: %v", err)
		return fmt.Errorf("failed to create markdown transformer: %w", err)
	}

	messages, err := transformer.Transform(notification, "markdown")
	if err != nil {
		global.Logger.Errorf("转换通知内容失败: %v", err)
		return fmt.Errorf("failed to transform notification: %w", err)
	}

	webhookURL, err := utils.GetWebhookURL(platform)
	if err != nil {
		global.Logger.Errorf("获取%s webhook URL失败: %v", platform, err)
		return err
	}

	if messages == nil {
		global.Logger.Info("没有有效的告警需要发送，跳过")
		return nil
	}

	global.Logger.Infof("准备通过%s发送%d条告警消息", platform, len(notification.Alerts))
	return s.sendWebhookMessage(platform, messages, webhookURL)
}

func (s *NotificationService) sendDingNotification(notification config.Notification, platform string) error {
	transformer, err := s.transformerFactory.CreateTransformer("dingding")
	if err != nil {
		return fmt.Errorf("failed to create dingding transformer: %w", err)
	}

	messages, err := transformer.Transform(notification, "dingding")
	if err != nil {
		return fmt.Errorf("failed to transform notification: %w", err)
	}

	webhookURL, err := utils.GetWebhookURL(platform)
	if err != nil {
		return err
	}

	if messages == nil {
		return nil
	}

	// 直接发送消息，不再使用userManager
	return s.sendWebhookMessage(platform, messages, webhookURL)
}

func (s *NotificationService) SendEmailNotification(notification config.Notification) (*config.EmailMessage, error) {
	global.Logger.Debug("开始创建邮件通知转换器")
	transformer, err := s.transformerFactory.CreateTransformer("email")
	if err != nil {
		global.Logger.Errorf("创建邮件转换器失败: %v", err)
		return nil, fmt.Errorf("failed to create email transformer: %w", err)
	}

	global.Logger.Debugf("转换邮件通知内容，告警数量: %d", len(notification.Alerts))
	emailMessage, err := transformer.Transform(notification, "email")
	if err != nil {
		global.Logger.Errorf("转换邮件通知内容失败: %v", err)
		return nil, fmt.Errorf("failed to transform email notification: %w", err)
	}

	msg, ok := emailMessage.(*config.EmailMessage)
	if !ok {
		global.Logger.Error("邮件消息类型无效")
		return nil, fmt.Errorf("invalid email message type")
	}

	global.Logger.Debugf("邮件通知内容准备完成，主题: %s", msg.Subject)
	return msg, nil
}

func (s *NotificationService) sendEmailMessage(message *config.EmailMessage) error {
	if message == nil {
		global.Logger.Error("邮件消息为空")
		return fmt.Errorf("email message is nil")
	}

	global.Logger.Infof("开始发送邮件，主题: %s", message.Subject)
	err := utils.SendEmail(message.Subject, message.Body)
	if err != nil {
		global.Logger.Errorf("发送邮件失败: %v", err)
		return fmt.Errorf("send email failed: %w", err)
	}

	global.Logger.Infof("邮件发送成功，主题: %s", message.Subject)
	return nil
}

func (s *NotificationService) sendWebhookMessage(platform string, message interface{}, webhookURL string) error {
	global.Logger.Infof("开始发送%s通知，URL: %s", platform, webhookURL)

	// 其他平台处理逻辑保持不变
	global.Logger.Debugf("原始消息内容: %+v", message)

	var messages []interface{}
	global.Logger.Debug("处理消息格式转换")

	switch v := message.(type) {
	case *config.QyWeChatMarkdown:
		global.Logger.Debug("处理企业微信Markdown格式消息")
		_, contents := utils.SplitCombinedAlerts(v.Markdown.Content)
		for i, content := range contents {
			global.Logger.Debugf("企业微信第%d条分割消息内容: %s", i+1, content.Markdown.Content)
			messages = append(messages, &config.QyWeChatMarkdown{
				MsgType: "markdown",
				Markdown: config.Markdown{
					Content: content.Markdown.Content,
				},
			})
		}
	case *config.DingDingMarkdown:
		global.Logger.Debug("处理钉钉Markdown格式消息")
		// 添加调试日志打印原始消息
		data, _ := json.Marshal(v)
		global.Logger.Debugf("原始钉钉消息: %s", string(data))

		contents, _ := utils.SplitCombinedAlerts(v.Markdown.Text)
		for i, content := range contents {
			global.Logger.Debugf("钉钉第%d条分割消息内容 - 标题: %s, 内容: %s",
				i+1, content.Markdown.Title, content.Markdown.Text)
			messages = append(messages, &config.DingDingMarkdown{
				MsgType: "markdown",
				Markdown: config.Dmarkdown{
					Title: content.Markdown.Title,
					Text:  content.Markdown.Text,
				},
				At: v.At, // 确保At字段被保留
			})
		}
	case string:
		global.Logger.Debug("处理字符串格式消息")
		_, contents := utils.SplitCombinedAlerts(v)
		for _, content := range contents {
			messages = append(messages, &config.QyWeChatMarkdown{
				MsgType: "markdown",
				Markdown: config.Markdown{
					Content: content.Markdown.Content,
				},
			})
		}
	default:
		global.Logger.Debug("处理未知格式消息，尝试JSON序列化")
		data, err := json.Marshal(message)
		if err != nil {
			global.Logger.Errorf("JSON序列化失败: %v", err)
			return err
		}
		global.Logger.Debugf("序列化结果: %s", string(data))
		messages = []interface{}{message}
	}

	global.Logger.Infof("准备发送%d条%s消息", len(messages), platform)
	for i, msg := range messages {
		// 添加详细的调试日志
		data, _ := json.Marshal(msg)
		global.Logger.Debugf("第%d条消息JSON内容: %s", i+1, string(data))

		if err := utils.SendWebhookRequest(platform, msg, webhookURL); err != nil {
			global.Logger.Errorf("发送%s第%d条消息失败: %v", platform, i+1, err)
			return err
		}
	}

	global.Logger.Infof("%s通知发送完成", platform)
	return nil
}

func SendNotification(notification config.Notification, platform string) error {
	service := NewNotificationService()

	// 创建MessageGenerator实例
	msgGenerator, err := NewMessageGenerator()
	if err != nil {
		return fmt.Errorf("创建消息生成器失败: %w", err)
	}
	defer msgGenerator.redisUtil.Close()

	// 发送通知
	err = service.Send(notification, platform)
	if err != nil {
		return err
	}

	// 如果是恢复告警且发送成功，删除key
	if notification.Status == "resolved" {
		for _, alert := range notification.Alerts {
			if err := msgGenerator.ConfirmAlertResolution(alert.Fingerprint); err != nil {
				global.Logger.Errorf("删除告警key失败: %v", err)
			}
		}
	}

	return nil
}

func SendWeChatNotification(notification config.Notification) error {
	return SendNotification(notification, "wechat")
}

func SendToDingdingNotification(notification config.Notification) error {
	return SendNotification(notification, "dingding")
}

func SendEmailNotification(notification config.Notification) (*config.EmailMessage, error) {
	return NewNotificationService().SendEmailNotification(notification)
}
